iverilogfandomcom-20200214-history
Forum:Specify simulation runtime
Hi, I looked around online and at the documentation a little, and I can't seem to find a way to tell vvp how long it should run a simulation. Similar to the --stop-time option in GHDL, this allows users to specify a runtime in units like ns, ms, ps, etc. It would be rather convenient, I think, to be able to stop the simulation without adjust #time statements in the code. If such a feature isn't available at the moment and help is needed to put it in, perhaps I could help out in some way... Thanks, - harnhua Verilog will continue to ran as long as there are events to process. Usually when building a test suite you run a set of tests and when they are done you run the $finish task to tell the simulator you are done. To prevent a run away simulation you can add something like the following: initial begin #1_000_000; // Wait a long time in simulation units (adjust as needed). $display("Caught by trap"); $finish; end Verilog does not recognize the ns, ms, ps, etc. timeunits. SystemVerilog does and there was someone interested in adding this to Icarus, but I'm guessing they are busy with other things. Using $value$plusargs you could pass a value at run time, but that would be in the blocks simulation units not absolute units. Since $value$plusargs does not change the value if the argument is not found you can even give an appropriate default for the delay. If the above suggestions do not provide an adequate solution you would need to discuss any additions on the iverilog-devel mailing list (SourceForge). Cary 22:17, February 6, 2010 (UTC) ---- Hi, Thank you for responding so quickly. I didn't know that Verilog does not recognize timeunits--at least some of the standard PLI functions seem to return timeunits. I'll definitely explore the $value$plusargs method, and look around further for a non-intrusive method because it seems to be a (small) hassle to insert $finish statements in all my testbenches. Since few developers seem to be requesting this kind of --stop-time option in Icarus Verilog, probably it is standard practice for most simulation testbenches to have $finish statements, I guess. Thanks again, - harnhua Well there are time units and time precision in the timescale directive as in `timescale 1ns/10ps, but any delay you specify after a timescale directive is in these time units so #1.1; is a 1.1ns delay. There's no way to directly say #1.1ns; in plain Verilog. You need SystemVerilog for that and at the moment Icarus does not support much SystemVerilog. You could fake this using something like the following that you would have in a separate file that would be included when you compiled the other files: `timescale 1us/1ns module finish_sim; realtime delay; // This is exactly the same as a real. initial begin delay = 1.0; // Default 1.0us delay. #(delay); $display(); $finish; end endmodule You could make a couple of these depending on the timescale you wanted for the individual simulations. Not exactly as nice as the ghdl option, but you should be able to get the same basic functionality. I obviously didn't simulate this so you may need to tweak a few things to get it to work, but the basic idea is correct. Cary 06:37, February 7, 2010 (UTC) ---- Thank you again. I didn't mean to have you go to the trouble of coding an example for me! But it explains your idea perfectly. Using a simplified version of the module you suggested, I ran a couple of experiments with the counter example in http://iverilog.wikia.com/wiki/Getting_Started and everything worked as expected. module finish_sim; realtime delay = 100.0; #(delay); $finish; endmodule Output of counter example: VCD info: dumpfile dump.vcd opened for output At time 0, value = xx (x) At time 5, value = xx (x) At time 17, value = 00 (0) Without instantiating finish_sim in counter_tb, I compiled (iverilog counter_tb.v counter.v finish_sim.v) and ran. It worked as expected, ending the simulation after 100 cycles. Just an observation: counter_tb.v and counter.v didn't have timescale directives so at first, I didn't use a timescale in finish_sim as well. Interestingly, if I add `timescale 1s/ms into finish_sim, my delay has to be 1000 in order for the simulation to run for a meaningful amount of time. `timescale 1s/1ms module finish_sim; realtime delay = 1000.0; #(delay); $finish; endmodule As in, a value that used to change after #5 in counter_tb now changes after #5000. Output: VCD info: dumpfile dump.vcd opened for output At time 0, value = xx (x) At time 5000, value = xx (x) At time 17000, value = 00 (0) Changing the timescale in finish_sim to 1000s/1s restores counter_tb's timeunits to their original precision. It's as if Icarus Verilog assumes a default of 1000s/1s for counter_tb, if that makes any sense. Not sure what to make of that, but perhaps it might be of interest. Thanks, - harnhua A couple of things. The display of a time using %t is by default dependent on the minimum time precision. So I would expect the numbers displayed to be 1000 times larger. I would not expect the actual delay to change. I know Icarus had problems with this in older version (it didn't scale a variable delay). Which version are you running? The delay should by 100 timeunits not 100 timeprecision steps. I verified that both the latest V0.9 (V0.9.2) and development (V0.10.devel) work as I expect. They scale the 100 time units to the the appropriate precision (multiply the variable by 1000) before performing the delay. Cary 17:47, February 8, 2010 (UTC) ---- That explains the time unit scaling, thank you. I was using V0.9.devel (20070608) which was obtained using the yum RPM utilty in Fedora 8. When I upgraded to V0.9.2 (from the git repository), delays work as expected. Thanks, Harnhua 7:31, February 9, 2010 (UTC)